<template>
  <div class="demand">
    <el-row class="demand-tree" :gutter="20">
      <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
        <ContentWrap class="h-1/1">
          <el-input v-model="filterText" style="width: 240px" placeholder="请输入关键字" />
          <el-button type="primary" plain style="margin-left: 10px" @click="view()">预览</el-button>
          <!-- <el-button type="primary" plain style="margin-left: 10px">导入Excel</el-button> -->
          <el-tree
            :data="dataSource"
            ref="treeRef"
            node-key="id"
            default-expand-all
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            :props="defaultProps"
            class="tree"
            :highlight-current="true"
            :indent="22"
            @node-click="handleNodeClick"
          >
            <template #default="{ node, data }">
              <!-- 非叶子 -->
              <span
                v-if="!node.isLeaf"
                style="display: flex; align-items: center"
                :class="{ disalbed: data.isRoot ,current: defaultId == data.id }"
              >
                <span @click.stop="node.expanded = !node.expanded">
                  <el-icon v-if="node.expanded" style="margin: 0 6px 0 2px" size="16">
                    <FolderOpened />
                  </el-icon>
                  <el-icon v-else style="margin: 0 6px 0 2px" size="16">
                    <Folder />
                  </el-icon>
                </span>
                <small>{{ node.label }}</small>
                <span v-if="data.demandNum > 0" class="num"> （{{ data.demandNum }}） </span>
              </span>
              <!-- 叶子 -->
              <span
                v-else
                style="display: flex; align-items: center"
                :class="{ disalbed: data.isRoot }"
              >
                <el-icon style="margin: 0 6px 0 2px" size="16">
                  <Document />
                </el-icon>
                <small>{{ node.label }}</small>
              </span>
              <!-- 操作 -->
              <span>
                <a @click.stop="append(data)" v-if="addPermission">
                  <el-icon> <CirclePlus /> </el-icon
                ></a>
                <a
                  style="margin-left: 8px"
                  @click.stop="remove(node, data)"
                  v-if="!data.isRoot && delPermission"
                >
                  <el-icon>
                    <Delete />
                  </el-icon>
                </a>
              </span>
            </template>
          </el-tree>
        </ContentWrap>
      </el-col>
      <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
        <ContentWrap class="h-1/1">
          <el-form
            ref="formRef"
            v-loading="formLoading"
            :model="formData"
            :rules="formRules"
            label-width="100px"
            v-show="selectNode"
            :disabled="dataSource && dataSource.length && !dataSource[0].children.length"
          >
            <el-form-item label="名称:" prop="name">
              <el-input v-model="formData.name" placeholder="请输入名称" />
            </el-form-item>
            <el-form-item label="标识:" prop="code">
              <el-input v-model="formData.code" placeholder="请输入标识" :disabled="true" />
            </el-form-item>
            <el-form-item label="描述:" prop="description">
              <el-input
                v-model="formData.description"
                placeholder="请输入描述"
                type="textarea"
                :rows="6"
              />
            </el-form-item>
            <el-form-item label="需求类型:" prop="requestType">
              <el-select v-model="formData.requestType" clearable placeholder="请选择需求类型">
                <el-option
                  v-for="item in getIntDictOptions(DICT_TYPE.REQUEST_TYPE)"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="状态:" prop="status">
              <el-select v-model="formData.status" clearable placeholder="请选择状态">
                <el-option
                  v-for="status in statusList"
                  :key="status.value"
                  :label="status.label"
                  :value="status.value * 1"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="开发责任人:" prop="developerId">
              <el-select v-model="formData.developerId" clearable placeholder="请选择开发责任人">
                <el-option
                  v-for="duty in dutyList"
                  :key="duty.id"
                  :label="duty.nickname"
                  :value="duty.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="save" v-if="updatePermission">保存</el-button>
            </el-form-item>
          </el-form>
        </ContentWrap>
      </el-col>
    </el-row>
    <ViewCom ref="viewRef" />
  </div>
</template>

<script setup lang="ts">
import * as DemandApi from '@/api/demand'
import { CirclePlus, Delete, FolderOpened, Folder, Document } from '@element-plus/icons-vue'
import ViewCom from './View.vue'
import { useAppStore } from '@/store/modules/app'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const appStore = useAppStore()
const projectId = computed(() => appStore.getSelectProject)
const { currentRoute } = useRouter() // 路由对象
const { query } = unref(currentRoute)
const loading = ref(false) // 列表的加载中
const dataSource = ref([] as any)
const statusList = ref([] as any)
const dutyList = ref([] as any)
const filterText = ref('')
const treeRef = ref()
const formLoading = ref(false) // 表单的加载中:1）修改时的数据加载；2）提交的按钮禁用
const formData = ref({} as any)
const defaultId = ref('')
const formRules = reactive({
  name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
  code: [{ required: true, message: '标识不能为空', trigger: 'blur' }],
  description: [{ required: true, message: '描述不能为空', trigger: 'blur' }],
  requestType: [{ required: true, message: '需求类型不能为空', trigger: 'change' }]
})
const defaultProps = {
  children: 'children',
  label: 'name',
  disabled: 'disabled'
}
const role = computed(() => query.role as any)
const selectNode = ref('')
const addPermission = computed(() => ['admin', 'projectManager', 'developer'].includes(role.value))
const delPermission = computed(() => ['admin', 'projectManager'].includes(role.value))
const updatePermission = computed(() =>
  ['admin', 'projectManager', 'developer'].includes(role.value)
)

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

// 过滤
const filterNode = (value, data) => {
  if (!value) return true
  return data.name.includes(value) || data.code.includes(value)
}

// 获取树列表
const getList = async () => {
  resetForm()
  loading.value = true
  try {
    const data = await DemandApi.getDemandTree({ id: query.id })
    data.disabled = true
    dataSource.value = [data]
    handleNodeClick(selectNode.value)
  } finally {
    loading.value = false
  }
}
// 获取状态列表
const getStatusList = async () => {
  let data = await DemandApi.getDemandStatus()
  statusList.value = data
}
// 获取开发责任人列表
const getDutyList = async () => {
  let data = await DemandApi.getProjectDevMember({ projectId: projectId.value })
  dutyList.value = data
}

// 新增
const append = async (data) => {
  let result = await DemandApi.getDemandInfo({ id: data.id })
  const newChild = { name: '新建功能点', code: result.code + '-', children: [], parentId: data.id }
  if (!data.children) {
    data.children = []
  }
  data.children.push(newChild)
  dataSource.value = [...dataSource.value]
  handleNodeClick(newChild)
}
// 删除
const remove = async (node, data) => {
  if (data.id) {
    try {
      await message.delConfirm()
      await DemandApi.deleteDemandTree({ id: data.id })
      message.success(t('common.delSuccess'))
      // 刷新列表
      await getList()
    } catch {}
  } else {
    const parent = node.parent
    const children = parent.data.children || parent.data
    const index = children.findIndex((d) => d.id === data.id)
    children.splice(index, 1)
    dataSource.value = [...dataSource.value]
  }
}
const viewRef = ref()

// 预览
const view = () => {
  viewRef.value.open(dataSource)
}
// 节点点击
const handleNodeClick = async (data) => {
  if (!data || data.isRoot) {
    return
  }
  defaultId.value = data.id || ''
  selectNode.value = data
  let result = {} as any
  if (data.id) {
    result = await DemandApi.getDemandInfo({ id: data.id })
  } else {
    result = data
  }
  formData.value = {
    ...result,
    name: result.name || data.name,
    parentId: data.parentId
  }
  formRef.value.clearValidate()
}
// 保存
const save = async () => {
  // 校验表单
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  loading.value = true
  try {
    if (formData.value.id) {
      await DemandApi.updateDemandTree({
        ...formData.value,
        projectId: projectId.value,
        projectVersionId: query.id
      })
      message.success(t('common.updateSuccess'))
    } else {
      await DemandApi.createDemandTree({
        ...formData.value,
        projectId: projectId.value,
        projectVersionId: query.id
      })
      message.success(t('common.createSuccess'))
    }
    // 刷新列表
    await getList()
  } finally {
    loading.value = false
  }
}
const formRef = ref() // 表单 Ref

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    name: '',
    code: '',
    description: '',
    status: '',
    developerId: '',
    requestType: ''
  }
  formRef.value?.resetFields()
}
/** 初始化 **/
onMounted(() => {
  getList()
  getStatusList()
  getDutyList()
})
</script>

<style scoped lang="scss">
.demand {
  height: calc(100vh - 175px);

  .el-row {
    height: 100%;

    .el-col {
      height: 100%;

      :deep(.el-card__body) {
        height: calc(100% - 40px);

        > div {
          height: 100%;

          .el-tree {
            height: calc(100% - 50px);
            overflow: auto;
          }
        }
      }
    }
  }
}
.current {
  display: block;
  background-color: var(--el-color-primary-light-9);
  width: 100%;

  small {
    color: #5e7ce0;
  }
}

.num {
  color: var(--el-color-primary);
  border-radius: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 0px 0 0px;
  font-size: 12px;
}

.disalbed {
  width: 100%;
  cursor: not-allowed;
}

:deep(.el-tree) {
  padding: 10px 10px 10px 0;

  .el-tree-node {
    .el-tree-node__content {
      display: flex;
      justify-content: space-between;
    }

    i.el-tree-node__expand-icon {
      svg {
        display: none;
      }
    }

    i.el-tree-node__expand-icon {
      display: none;
    }
  }

  .el-tree-node.is-current {
    .el-tree-node__content {
      small {
        color: #5e7ce0;
      }
    }

    .el-tree-node__children {
      small {
        color: unset;
      }
    }
  }

  /* ^ 树节点 */
  .el-tree-node {
    position: relative;
    width: auto;
    padding-left: 13px;

    &::before {
      width: 1px;
      height: 100%;
      content: '';
      position: absolute;
      top: -38px;
      bottom: 0;
      left: 0;
      right: auto;
      border-width: 1px;
      border-left: 1px solid #b8b9bb;
    }

    &::after {
      width: 13px;
      height: 13px;
      content: '';
      position: absolute;
      z-index: 0;
      left: 0;
      right: auto;
      top: 12px;
      bottom: auto;
      border-width: 1px;
      border-top: 1px solid #b8b9bb;
    }

    .el-tree-node__content {
      position: relative;
      z-index: 1;
      padding-left: 0 !important;
    }

    .el-tree-node__children {
      padding-left: 12px;
    }

    &:last-child::before {
      height: 50px;
    }
  }

  > .el-tree-node {
    padding-left: 0;

    &::before {
      border-left: none;
    }

    &::after {
      border-top: none;
    }
  }
}
</style>
